/*******************************************************************************
 * Copyright (c) 2007 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.extensionpoints.transformation.definition;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import org.eclipse.swt.graphics.Image;

import com.cea.papyrus.extensionpoints.transformation.Activator;

/**
 * Extension Point for transformations in Papyrus
 */
public class Group extends AbstractExtensionPoint {
	
	/** Array that stores registered groups of transformation */
	private static Group[] groups;
	
	private final Transformation[] transformations;
	
	/** the extension to "parse" */
	public final IConfigurationElement configElement;
	
	/** value of the name attribute */
	private final String name;
	
	/** the value of the icon path attribute */
	private final String iconPath;


	/**
	 * Icon getter
	 * @return the icon which path is in extension
	 */
	public Image getIcon() {
		return getImage(iconPath, configElement);
	}

	/**
	 * Returns the set of transformations registered in the platform
	 * @return the set of transformations registered in the platform
	 */
	public static Group[] getRegisteredGroups() {
		
		// if it has already been computed, return the old computed value
		if (groups != null) {
			return groups;
		}
		
		// it was not already computed, returns the new Collection of Transformation
		List<Group> groupos = new ArrayList<Group>();
			
		// Reading data from plug-ins
		IConfigurationElement[] configElements = Platform.getExtensionRegistry().getConfigurationElementsFor(TransformationExtIds.TRANSFORMATION_EXTENSION_ID);		
		
		// Read configuration elements for the current extension
		for (int j = 0 ; j < configElements.length ; j++) {
			Group proxy = parseGroupExtension(configElements[j]);

			if (proxy != null) {
				groupos.add(proxy);
			}
		} // end of configElements loop	
		
		groups = groupos.toArray(new Group[groupos.size()]);
		return groups;
	}
	
	/**
	 * Returns a transformation, given elements from the ConfigurationElement
	 * @param configElt the element that declares the extension
	 * @return a new transformation, given the information of the specified configElt 
	 */
	private static Group parseGroupExtension(IConfigurationElement configElt) {
		
		// check that the ConfigElement is a Group
		if (! configElt.getName().equals(GroupExtIds.TAG_GROUP)) {
			return null;
		}
		// this is a group, tries to parse extension, and create the java corresponding class
		try {
			return new Group(configElt);
		} catch (Exception e) {
			
			String name = configElt.getAttribute(GroupExtIds.ATT_NAME);
			if (name == null) {
				name = "[missing id attribute]";
			}
			String msg = "Failed to load language with id "
							+ name + " in "
							+ configElt
								.getDeclaringExtension()
								.getExtensionPointUniqueIdentifier();
			
			Activator.log(msg, e);
			return null;
		}
	}
	
	/**
	 * Creates a new Transformation, according to the ConfigurationElement 
	 * @param configElt the configuration element corresponding to the transformation
	 */
	public Group(IConfigurationElement configElt) {
		this.configElement = configElt;
		
		name = getAttribute(configElt, GroupExtIds.ATT_NAME, "undefined", true);
		iconPath = getAttribute(configElt, GroupExtIds.ATT_ICON, null, false);
		
		// Retrieve owned transformations
		List<Transformation> transfos = new ArrayList<Transformation>();
			
		// Reading data from plug-ins
		IConfigurationElement[] ownedConfElts = configElt.getChildren();
		
		// Read configuration elements for the current extension
		for (int j = 0 ; j < ownedConfElts.length ; j++) {
			Transformation proxy = Transformation.parseTransformationExtension(ownedConfElts[j]);

			if (proxy != null) {
				transfos.add(proxy);
			}
		} // end of configElements loop	
		
		transformations = transfos.toArray(new Transformation[transfos.size()]);
	}
	
	/**
	 * Default constructor
	 */
	public Group() {
		this.configElement = null;
		name = "undefined";
		iconPath = "undefined";
		transformations = new Transformation[0];
	}

	/**
	 * Returns the qualified name of the module 
	 * @return the qualified name of the module
	 */
	public String getName() {
		return name;
	}
	
	/**
	 * Returns the icon name of the module 
	 * @return the icon name of the module
	 */
	public String getIconPath() {
		return iconPath;
	}
	
	/**
	 * Retrieve transformations owned by the group
	 * @return transformations owned by the group
	 */
	public Transformation[] getTransformations() {		
		return transformations;
	}
}
